﻿using ModelAccess.Concrete;
using ModelLayer;
using DTO;
using DataLayer;
using log4net;
using System.Collections.Generic;
using System;
using System.Data.Common;

namespace BusinessLayer
{
    public class UtenteLogic
    {

        private Compagnia compagniaDaInserire=null;
        private Gruppo gruppoDaInserire=null;
        private StatoSessione statoSessioneDaInserire=null;

        private static readonly ILog log = LogManager.GetLogger(
                   System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        public void updateRisposteUtente(Utente u)
        {
            using (UtentiHelper uh = new UtentiHelper())
            {
                if (u.Risposte.Count > 0)
                    uh.saveChanges(u);
            }


        }

        public UtenteLogged authenticate(DTOUtente dto)
        {

            return getUtente(dto, true);
        }
        public UtenteLogged getUtente(DTOUtente dto, bool authenticate)
        {
            Utente utenteDB;
            UtenteLogged ul = null;
            using (UtentiHelper uh = new UtentiHelper())
            {

                utenteDB = uh.getUtente(dto.Username);

                if (utenteDB != null)
                {
                    if ((authenticate) && (!MD5Helper.VerifyMd5Hash(dto.Password, utenteDB.Password)))
                    {
                       
                        ul = null;
                    }
                    else
                    {
                        if(authenticate)
                            log.Debug("Utente loggato:" + dto.Username);
                        Sessione s=uh.getSessioneAperta(dto.Username);
                        if (utenteDB.Sessioni.Count == 0)
                        {
                            log.Error("Attenzione utente " + utenteDB.Username + " senza sessione!");
                            utenteDB.Sessioni.Add(s);
                           
                        }
                        ul = new UtenteLogged() { utente = utenteDB };
                        using (WorkflowHelper wh = new WorkflowHelper())
                        {
                            Workflow w = wh.getWorkflow(utenteDB, utenteDB.Sessioni[0]);
                            if (w != null)
                            {
                                ul.grantModificaModello = true;
                            }
                            else
                            {
                                ul.grantModificaModello = false;
                            }
                            ul.grantVisualizzaProfilo = true;  
                            if (utenteDB.Gruppo.Id == "UTENTE")
                            {
                                if (utenteDB.Sessioni[0].StatoSessione.Id == "1")
                                    ul.grantVisualizzaProfilo = false;    
                            }
                            if (utenteDB.Gruppo.Id == "REVISORE")
                            {
                                ul.grantVisualizzaProfilo=true;
                                ul.grantModificaModello = true;
                            }
                            

                        }

                    }
                }

            }
            return ul;
        }
        public UtenteLogged storicizza(Sessione s)
        {

            using (UtentiHelper uh = new UtentiHelper())
            {
                uh.storicizzaModello(s, 2);
                return getUtente(new DTOUtente() { Username = s.Utente.Username }, false);
            }
        }
        public void deleteUtenti(List<DTOUtente> utentiList)
        {
            using (UtentiHelper uh = new UtentiHelper())
            {
                DbTransaction transaction = null;
                try
                {
                    transaction= uh.startTransaction();
                    foreach(DTOUtente u in utentiList)
                        uh.deleteUtente(new Utente() { Username=u.Username});
                    uh.commit(transaction);
                }
                catch (Exception e)
                {
                    if(transaction!=null)
                        uh.rollback(transaction);
                    throw e;
                }
            }
        }
        public UtenteLogged valida(Sessione s)
        {

            using (UtentiHelper uh = new UtentiHelper())
            {
                uh.storicizzaModello(s, 3);
                return getUtente(new DTOUtente() { Username = s.Utente.Username }, false);
            }
        }

        public List<DTOUtente> getSottoposti(Utente utente)
        {
            using (UtentiHelper uh = new UtentiHelper())
            {
               List<Utente> utenti= uh.getUtentiCompagnia(utente);
                List<DTOUtente> utentiDTO=new List<DTOUtente>();
                foreach(Utente u in utenti)
                {
                    if (u.Sessioni.Count == 0)
                    {
                        log.Error("Attenzione utente " + u.Username + " senza sessione!");
                    }
                    DTOUtente utenteDTO=new DTOUtente(){Username=u.Username,Nome=u.Nome,Cognome=u.Cognome,Email=u.Email,Stato=u.Sessioni[0].StatoSessione.Nome };
                    utentiDTO.Add(utenteDTO);
                }
                return utentiDTO;
            }
        }

        public bool inserisci(Utente utente,Utente superiore)
        {
            using (UtentiHelper uh = new UtentiHelper())
            {
               return inserisciUsingConnection(utente, superiore,uh);
            }
        }
        public bool inserisciUsingConnection(Utente utente, Utente superiore, UtentiHelper uh)
        {
            if(statoSessioneDaInserire==null)
                statoSessioneDaInserire = new StatoSessione() { Id = "1" }.MarkAsUnchanged();
            if(compagniaDaInserire==null)
                compagniaDaInserire = new Compagnia() { Id = superiore.Compagnia.Id }.MarkAsUnchanged();
            utente.Compagnia = compagniaDaInserire;
            if(gruppoDaInserire==null)
                gruppoDaInserire = new Gruppo() { Id = "UTENTE" }.MarkAsUnchanged();
            utente.Gruppo = gruppoDaInserire;
            
            utente.Password = MD5Helper.DoMd5Hash(utente.Password);
            utente.MarkAsAdded();
            Sessione s = new Sessione() {Aperto = "A", DataCreazione = DateTime.Now, StatoSessione = statoSessioneDaInserire };
            s.MarkAsAdded();
            utente.Sessioni.Add(s);
            Utente u = uh.getUtente(utente.Username);
            if (u != null)
                return false;
            uh.saveChanges(utente);
            return true;
        }
    }
}
